﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Geometry;
using System.Data.SQLite;
using System.Data;
using System.Data.Common;
//using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.PlottingServices;
//using Autodesk.AutoCAD.PlottingServices;
//using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using System.Threading;
using System.ComponentModel;
using System.Diagnostics;

namespace cadbom
{
    class CopyBlockDwg
    {
        //切出块
        public void wblockEntity()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
            Transaction trans = db.TransactionManager.StartTransaction();
            List<BlockReference> blks = GetBlockEntitys(doc);//获取文件中的所有块
            List<string> name = new List<string>();
            foreach (BlockReference item in blks)
            {
                using (Database newDb = new Database(true, false))
                {
                    BlockReference ent = trans.GetObject(item.Id, OpenMode.ForWrite) as BlockReference;
                    Move(ent, ent.Position, Point3d.Origin);
                    ObjectIdCollection newids = new ObjectIdCollection();
                    newids.Add(item.Id);

                    //***********************
                    BlockTableRecord blockTableRecord = (BlockTableRecord)trans.GetObject(ent.BlockTableRecord, OpenMode.ForRead);
                    // 遍历块定义中的所有对象并添加到 newIds
                    foreach (ObjectId objId in blockTableRecord)
                    {
                        try
                        {
                            //Entity ent1 = trans.GetObject(objId, OpenMode.ForWrite) as Entity;
                            //Move(ent1, ent1.GeometricExtents.MinPoint, Point3d.Origin);
                            newids.Add(objId);
                        }
                        catch (Autodesk.AutoCAD.Runtime.Exception ex)
                        {

                        }

                    }
                    //***********************




                    //dwg文件保存不能包含以下字符* 、\ / ? " < > |
                    if (!name.Contains(ent.Name) && !ent.Name.Contains('*'))
                    {
                        db.Wblock(newDb, newids, Point3d.Origin, DuplicateRecordCloning.Replace);
                        string FileName = @"D:\temp\" + ent.Name + ".dwg";
                        newDb.SaveAs(FileName, DwgVersion.Current);
                    }
                    ent.Erase();//删除
                }
            }
            docLock.Dispose();
            trans.Commit();
        }
        /// <summary>
        /// 指定基点与目标点移动实体
        /// </summary>
        /// <param name="ent">实体对象</param>
        /// <param name="BasePt">基点</param>
        /// <param name="TargetPt">目标点</param>
        public static void Move(Entity ent, Point3d basePt, Point3d targetPt)
        {
            Vector3d vec = targetPt - basePt;
            Matrix3d mt = Matrix3d.Displacement(vec);
            ent.TransformBy(mt);

        }
        /// <summary>
        /// 获取文档中的所有块
        /// </summary>
        /// <param name="newdoc"></param>
        /// <returns></returns>
        private static List<BlockReference> GetBlockEntitys(Document newdoc)
        {
            Database db = newdoc.Database;
            List<BlockReference> ents = new List<BlockReference>();
            List<string> blkNames = new List<string>();
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;//获取块表
                BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;//获取模型空间的块表记录
                foreach (ObjectId item in btr)
                {
                    Entity ent = trans.GetObject(item, OpenMode.ForWrite) as Entity;
                    if (ent.GetType() == typeof(BlockReference))
                    {
                        BlockReference block = ent as BlockReference;
                        if (!blkNames.Contains(block.Name))
                        {
                            ents.Add(block);
                            blkNames.Add(block.Name);
                        }
                    }
                }
                trans.Commit();
            }
            return ents;
        }

        public void ExportBlockToDwg()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();

            // 选择块
            PromptEntityOptions blockOptions = new PromptEntityOptions("\n请选择一个块: ");
            blockOptions.SetRejectMessage("\n选择的对象不是块。");
            blockOptions.AddAllowedClass(typeof(BlockReference), true);

            PromptEntityResult blockResult = ed.GetEntity(blockOptions);
            if (blockResult.Status != PromptStatus.OK)
                return;

            ObjectId blockId = blockResult.ObjectId;

            using (Transaction trans = doc.TransactionManager.StartTransaction())
            {
                BlockReference blockRef = (BlockReference)trans.GetObject(blockId, OpenMode.ForWrite);
                BlockTableRecord blockTableRecord = (BlockTableRecord)trans.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);

                // 创建新的 DWG 文件
                string newDwgPath = @"D:\temp\" + blockRef.Name + ".dwg"; // 替换为你的目标路径
                Database newDb = new Database(true, true);

                // 确保文件名不包含非法字符
                string fileName = blockRef.Name;
                if (fileName.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) == -1)
                {
                    ObjectIdCollection newIds = new ObjectIdCollection();
                    newIds.Add(blockId);

                    // 遍历块定义中的所有对象并添加到 newIds
                    foreach (ObjectId objId in blockTableRecord)
                    {
                        newIds.Add(objId);
                    }

                    // 将块及其内部对象写入新的 DWG 文件
                    db.Wblock(newDb, newIds, Point3d.Origin, DuplicateRecordCloning.Replace);

                    // 保存新的 DWG 文件
                    newDb.SaveAs(newDwgPath, DwgVersion.Current);
                    ed.WriteMessage("\n块内容已导出到 {newDwgPath}" + newDwgPath);
                }
                else
                {
                    ed.WriteMessage("\n文件名包含非法字符，无法保存。");
                }
                docLock.Dispose();


                // 删除块引用
                //blockRef.Erase();
                trans.Commit();
            }
        }

        public void XXA()
        {
            // 获取当前文档和数据库
            Document currentDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database currentDb = currentDoc.Database;
            Editor ed = currentDoc.Editor;

            // 定义块名称
            string blockName = "ExportedBlock";

            try
            {
                // 存储模型空间对象的 ObjectId 到数组中
                ObjectIdCollection objectIds = new ObjectIdCollection();

                using (Transaction tr = currentDb.TransactionManager.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(currentDb.BlockTableId, OpenMode.ForRead);
                    BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

                    // 遍历模型空间中的对象，存储它们的 ObjectId
                    foreach (ObjectId objId in modelSpace)
                    {
                        objectIds.Add(objId);
                    }

                    tr.Commit();
                }

                if (objectIds.Count == 0)
                {
                    ed.WriteMessage("\n模型空间中没有图元对象。");
                    return;
                }

                // 创建一个新图并插入块
                OpenNewDrawingAndInsertBlockFromArray(objectIds, currentDb, blockName);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n发生错误: {ex.Message}");
            }
        }

        private void OpenNewDrawingAndInsertBlockFromArray(ObjectIdCollection objectIds, Database sourceDb, string blockName)
        {
            // 打开新图
            Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Add("");
            Document newDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
            Database newDb = newDoc.Database;

            Editor newEd = newDoc.Editor;

            try
            {
                using (Transaction tr = newDb.TransactionManager.StartTransaction())
                {
                    // 创建一个新的块定义
                    BlockTable newBt = (BlockTable)tr.GetObject(newDb.BlockTableId, OpenMode.ForRead);
                    BlockTableRecord newBlock = new BlockTableRecord
                    {
                        Name = blockName
                    };

                    // 将新块定义添加到块表中
                    newBt.UpgradeOpen(); // 切换为写模式
                    ObjectId newBlockId = newBt.Add(newBlock);
                    tr.AddNewlyCreatedDBObject(newBlock, true);

                    // 克隆源数据库中的对象到新块定义
                    IdMapping idMap = new IdMapping();
                    sourceDb.WblockCloneObjects(objectIds, newBlockId, idMap, DuplicateRecordCloning.Replace, false);

                    // 在新图中插入块
                    BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(newBt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                    BlockReference blockRef = new BlockReference(Point3d.Origin, newBlockId);
                    modelSpace.AppendEntity(blockRef);
                    tr.AddNewlyCreatedDBObject(blockRef, true);

                    docLock.Dispose();
                    tr.Commit();

                    newEd.WriteMessage("\n块 '{blockName}' 已成功插入到新图中。");
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                newEd.WriteMessage("\n发生错误: {ex.Message}");
            }
        }
        public void openCadFile(String filepath)
        {
            string blockName = "CXHS"; // 替换为你要查找的块名称

            try
            {
                // 创建 AutoCAD 应用程序对象
                AcadApplication acadApp = new AcadApplication();
                acadApp.Visible = true;

                // 打开 DWG 文件
                AcadDocument acadDoc = acadApp.Documents.Open(@"D:\工程图\11HZXC304-10.dwg");

                //MessageBox.Show("DWG 文件已成功打开。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                // 执行 AutoCAD 内部命令，例如缩放全图
                //string command = "ZOOM ALL\n";
                //acadDoc.SendCommand(command);   
                // 查找并选中指定名称的块
                //SelectBlocksByName(acadDoc, blockName);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("打开文件时出错：{" + ex.Message + "}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void CopyToNewDwgCommand()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database sourceDb = doc.Database;
            Editor ed = doc.Editor;

            // 用户拉框选择对象
            PromptSelectionOptions options = new PromptSelectionOptions();
            options.MessageForAdding = "\n选择要复制的对象: ";
            PromptSelectionResult selResult = ed.GetSelection(options);
            if (selResult.Status != PromptStatus.OK) return;

            SelectionSet selection = selResult.Value;
            ObjectId[] selectedIds = selection.GetObjectIds();
            ObjectIdCollection idCollection = new ObjectIdCollection(selectedIds);

            // 创建新数据库
            using (Database destDb = new Database(true, true))
            {
                // 获取目标数据库的模型空间ID
                ObjectId destModelSpaceId;
                using (Transaction destTrans = destDb.TransactionManager.StartTransaction())
                {
                    BlockTable destBt = destTrans.GetObject(destDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    destModelSpaceId = destBt[BlockTableRecord.ModelSpace];
                    destTrans.Commit();
                }

                // 克隆对象到目标数据库
                using (Transaction sourceTrans = sourceDb.TransactionManager.StartTransaction())
                {
                    try
                    {
                        IdMapping idMap = new IdMapping();
                        sourceDb.WblockCloneObjects(
                            idCollection,
                            destModelSpaceId,  // 关键：添加目标块表记录ID
                            idMap,
                            DuplicateRecordCloning.Replace,
                            false
                        );

                        // 保存新文件
                        string fileName = "CopiedObjects_{DateTime.Now:yyyyMMddHHmmss}.dwg";
                        destDb.SaveAs(fileName, DwgVersion.Current);
                        ed.WriteMessage("\n文件已保存至: {fileName}");
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        ed.WriteMessage("\n错误: {ex.Message}");
                    }
                    finally
                    {
                        sourceTrans.Commit();
                    }
                }
            }
        }

        //

        public void ExportToNewDwgEnhanced()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database sourceDb = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                // 步骤1：用户选择对象
                PromptSelectionResult selResult = ed.GetSelection();
                if (selResult.Status != PromptStatus.OK || selResult.Value.Count == 0)
                {
                    ed.WriteMessage("\n未选择任何对象，操作已取消。");
                    return;
                }

                // 步骤2：获取保存路径
                System.Windows.Forms.SaveFileDialog saveDlg = new System.Windows.Forms.SaveFileDialog
                 {
                     Filter = "AutoCAD 文件 (*.dwg)|*.dwg",
                     Title = "保存新DWG文件",
                     FileName = "ExportDrawing.dwg",
                     DefaultExt = "dwg"
                 };

                if (saveDlg.ShowDialog() != DialogResult.OK)
                {
                    ed.WriteMessage("\n用户取消保存操作。");
                    return;
                }

                // 步骤3：创建新数据库
                using (Database newDb = new Database(false, true))
                {
                    // 步骤4：克隆对象
                    CloneSelectionWithDependencies(
                        sourceDb,
                        selResult.Value.GetObjectIds(),
                        newDb);

                    // 步骤5：保存文件
                    SaveDatabaseWithRetry(newDb, saveDlg.FileName, ed);
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n严重错误: {ex.GetType().Name}\n{ex.Message}");
            }
        }

        private void CloneSelectionWithDependencies(
            Database sourceDb,
            ObjectId[] objectIds,
            Database targetDb)
        {
            using (Transaction tr = sourceDb.TransactionManager.StartTransaction())
            using (IdMapping idMap = new IdMapping())
            {
                ObjectIdCollection idCollection = new ObjectIdCollection(objectIds);

                // 获取目标模型空间
                BlockTableRecord targetMs = GetModelSpace(targetDb);

                // 克隆对象及其依赖项
                sourceDb.WblockCloneObjects(
                    idCollection,
                    targetMs.ObjectId,
                    idMap,
                    DuplicateRecordCloning.Replace,
                    false);

                tr.Commit();
            }
        }

        private BlockTableRecord GetModelSpace(Database db)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                return tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
            }
        }

        private void SaveDatabaseWithRetry(Database db, string path, Editor ed)
        {
            try
            {
                // 设置保存选项
                DwgVersion version = DwgVersion.Current;
                db.SaveAs(path, version);

                ed.WriteMessage("\n成功保存文件到: {path}");

                // 可选：打开资源管理器
                if (MessageBox.Show("是否要打开文件所在位置？",
                    "保存成功",
                    MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", "/select,\"{path}\"");
                }
            }
            catch (System.Exception ex)
            {

            }
        }

        //
        public void InitDomainConfig()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor editor = doc.Editor;
            // 指定配置文件的路径
            string configFilePath = @"c:\temp\block_corners.txt"; //"E:\\Program Files\\Autodesk\\AutoCAD 2014\\erptestdll\\config.txt";
            try
            {
                // 读取文本文件的所有行
                string[] lines = File.ReadAllLines(configFilePath);

                // 遍历每一行并处理配置信息
                int i = 0;
                string[] pointA = null;
                string[] pointB = null;
                foreach (string line in lines)
                {
                    i++;
                    // 假设配置文件的每一行都是以"键=值"的格式存储
                    string[] keyValue = line.Split(':');
                    if (keyValue.Length == 2)
                    {
                        string key = keyValue[0].Trim();
                        string value = keyValue[1].Trim();

                        try
                        {

                            if (i == 1 || i == 3)
                            {
                                pointA = value.Split(',');
                            }
                            if (i == 2 || i == 4)
                            {
                                pointB = value.Split(',');
                                Point3d first = new Point3d(Double.Parse(pointA[0]), Double.Parse(pointA[1]), 0);
                                Point3d second = new Point3d(Double.Parse(pointB[0]), Double.Parse(pointB[1]), 0);
                                SelectBlock2Pdf toPdf = new SelectBlock2Pdf();
                                toPdf.PlotBlockColToPDF(first, second, "code" + i);
                            }


                        }
                        catch (System.Exception e)
                        {
                            editor.WriteMessage(e.ToString());
                        }
                    }
                }
            }
            catch (IOException e)
            {
                editor.WriteMessage("读取配置文件时发生错误: " + e.Message);
            }

        }

        private string GetLispResult()
        {
            // 获取当前文档的编辑器
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            // 读取用户输入或返回值
            PromptStringOptions options = new PromptStringOptions("\n请输入返回值: ");
            PromptResult result = ed.GetString(options);

            if (result.Status == PromptStatus.OK)
            {
                return result.StringResult;
            }
            return null;
        }

//        // 定义要执行的LISP语句
//        string lispCode = @"(defun c:GetBlockCorners (/ ent obj minpt maxpt)
//  (vl-load-com) ; 确保 ActiveX 支持已加载
//  (setq ent (car (entsel ""\n请选择块参照: ""))) ; 选择对象
//  
//  (cond
//    ((not ent)
//      (princ ""\n未选择对象。""))
//    
//    ((/= ""INSERT"" (cdr (assoc 0 (entget ent))))
//      (princ ""\n所选对象不是块参照。""))
//    
//    (T
//      (setq obj (vlax-ename->vla-object ent)) ; 转换为 VLA 对象
//      (vla-GetBoundingBox obj 'minpt 'maxpt) ; 获取边界框
//      
//      (setq
//        minpt (vlax-safearray->list minpt) ; 转换最小点坐标
//        maxpt (vlax-safearray->list maxpt) ; 转换最大点坐标
//      )
//      
//      (princ (strcat ""\n块的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)))
//      (princ (strcat ""\n块的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)))
//    )
//  )
//  (princ)
//)
//(c:GetBlockCorners)";

        public void ExecuteLispbb()
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // 生成 UUID 作为文件名
            string uuid = Guid.NewGuid().ToString();
            string filePath = "C:\\temp\\" + uuid + ".txt";

            // 定义要执行的 LISP 语句，使用 string.Format 动态插入文件名
            string lispCodeTemplate = @"
(defun c:GetBlockCornersall (/ ss i ent obj minpt maxpt file)
    (vl-load-com) ; 确保 ActiveX 支持已加载
    ; 创建选择集，过滤出所有名为 ""A4横图框"" 的块参照
    (setq ss (ssget ""_X"" '((0 . ""INSERT"") (2 . ""A4横图框"")))) 

    (cond
        ((not ss)
            (princ ""\n未找到名为 A4横图框 的块参照。""))
        
        (T
            ; 打开文件以写入坐标信息
            (setq file (open ""{0}"" ""w""))
            (if file
                (progn
                    ; 遍历选择集中的每个块参照
                    (repeat (setq i (sslength ss))
                        (setq ent (ssname ss (setq i (1- i)))) ; 获取当前块参照的实体名
                        (setq obj (vlax-ename->vla-object ent)) ; 转换为 VLA 对象
                        (vla-GetBoundingBox obj 'minpt 'maxpt) ; 获取边界框
                        
                        (setq
                            minpt (vlax-safearray->list minpt) ; 转换最小点坐标
                            maxpt (vlax-safearray->list maxpt) ; 转换最大点坐标
                        )
                        
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)))
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)))
                    )
                    ; 关闭文件
                    (close file)
                )
                (princ ""\n无法打开文件进行写入操作。"")
            )
        )
    )
    (princ ""<LISP_EXECUTION_COMPLETED>"")
)
(c:GetBlockCornersall)";

            string lispCode = string.Format(lispCodeTemplate, filePath);

            try
            {
                // 获取 CMDECHO 系统变量的值
                ResultBuffer rb = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("CMDECHO") as ResultBuffer;
                int oldCmdecho = 0;
                if (rb != null)
                {
                    foreach (TypedValue tv in rb)
                    {
                        if (tv.TypeCode == (int)DxfCode.Int32)
                        {
                            oldCmdecho = (int)tv.Value;
                            break;
                        }
                    }
                }

                // 关闭命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0);

                // 执行 LISP 语句
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute(lispCode + "\n", true, false, false);

                // 等待文件生成
                DateTime startTime = DateTime.Now;
                TimeSpan timeout = TimeSpan.FromMinutes(2);
                bool fileExists = false;

                while (!fileExists && (DateTime.Now - startTime) < timeout)
                {
                    fileExists = File.Exists(filePath);
                    if (!fileExists)
                    {
                        Thread.Sleep(100); // 每隔 100 毫秒检查一次
                    }
                }

                if (!fileExists)
                {
                    ed.WriteMessage("\n文件生成超时，未在两分钟内完成。");
                }
                else
                {
                    // 读取文件内容
                    string fileContent = File.ReadAllText(filePath);
                    ed.WriteMessage("\n文件内容:\n" + fileContent);
                }

                // 恢复命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", oldCmdecho);

                ed.WriteMessage("\nLISP 语句执行尝试结束！");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n执行 LISP 语句时出错: " + ex.Message);
            }
        }

        public void ExecuteLisp(Action<String> callback)
        {
            // 获取当前文档和数据库
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            
            // 定义文件路径
            string filePath = @"C:\erptestdll\block_corners.txt";

            // 检查文件是否存在
            if (File.Exists(filePath))
            {
                // 如果文件存在，则删除
                File.Delete(filePath);
            }

            // 定义要执行的LISP语句
            string lispCode = @"(defun c:GetBlockCornersall (/ ss i ent obj minpt maxpt file)
    (vl-load-com) ; 确保 ActiveX 支持已加载
    ; 创建选择集，过滤出所有名为 ""A4横图框"" 的块参照
    (setq ss (ssget ""_X"" '((0 . ""INSERT"") (2 . ""A4横图框"")))) 

    (cond
        ((not ss)
            (princ ""\n未找到名为 A4横图框 的块参照。""))
        
        (T
            ; 打开文件以写入坐标信息
            (setq file (open ""C:/erptestdll/block_corners.txt"" ""w""))
            (if file
                (progn
                    ; 遍历选择集中的每个块参照
                    (repeat (setq i (sslength ss))
                        (setq ent (ssname ss (setq i (1- i)))) ; 获取当前块参照的实体名
                        (setq obj (vlax-ename->vla-object ent)) ; 转换为 VLA 对象
                        (vla-GetBoundingBox obj 'minpt 'maxpt) ; 获取边界框
                        
                        (setq
                            minpt (vlax-safearray->list minpt) ; 转换最小点坐标
                            maxpt (vlax-safearray->list maxpt) ; 转换最大点坐标
                        )
                        
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)) file)
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的左下角坐标: "" (rtos (car minpt) 2 2) "", "" (rtos (cadr minpt) 2 2)))
                        (princ (strcat ""\n块 "" (vla-get-name obj) "" 的右上角坐标: "" (rtos (car maxpt) 2 2) "", "" (rtos (cadr maxpt) 2 2)))
                    )
                    ; 关闭文件
                    (close file)
                )
                (princ ""\n无法打开文件进行写入操作。"")
            )
        )
    )
    (princ)
)
(c:GetBlockCornersall)";

            try
            {
                // 获取 CMDECHO 系统变量的值
                ResultBuffer rb = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("CMDECHO") as ResultBuffer;
                int oldCmdecho = 0;
                if (rb != null)
                {
                    foreach (TypedValue tv in rb)
                    {
                        if (tv.TypeCode == (int)DxfCode.Int32)
                        {
                            oldCmdecho = (int)tv.Value;
                            break;
                        }
                    }
                }

                // 关闭命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0);

                // 执行LISP语句
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute(lispCode + "\n", true, false, false);


                // 恢复命令行回显
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", oldCmdecho);
                // 启动新任务检查文件
                Task.Run(() => CheckFileExists(filePath,callback));

                ed.WriteMessage("\nLISP语句执行成功！");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n执行LISP语句时出错: " + ex.Message);
            }
        }
        private void CheckFileExists(string filePath,Action<String> callback)
        {
            // 循环检查文件是否存在，最多检查 10 次
            for (int i = 0; i < 10; i++)
            {
                // 检查文件是否存在
                if (File.Exists(filePath))
                {
                    if (callback != null)
                    {
                        callback.Invoke("ok");
                    }
                    return; // 如果文件存在，退出方法
                }
                else
                {
                    Console.WriteLine("文件不存在，等待 5 秒后重试...");
                }

                // 暂停 5 秒
                Thread.Sleep(5000);
            }
        }

        public void opendwgfile()
        {
            AcadDocument AcdDoc = new AcadDocument();
            AcadDocument doc = null;

            doc = AcdDoc.Application.Documents.Open(@"d:\工程图\221010323电池柜-框架-2D(2)(2).DWG", true, null);
            doc.SetVariable("BACKGROUNDPLOT", 0);//前台打印
            doc.Application.ZoomExtents();
            doc.ActiveLayout.ConfigName = "DWG To PDF.pc3";//使用的打印机设置名称 页面设置名称
            List<object[]> ls_rec = new List<object[]>();
            for (int i = 0; i < doc.ModelSpace.Count; i++)
            {

                //AcadEntity cadObject = doc.ModelSpace.Item(i);
                dynamic cadObject = doc.ModelSpace.Item(i);

                Console.WriteLine(cadObject.EntityName);

                //AcDbBlockReference
                //AcDbMText
                //AcDbLine
                //AcDbPolyline
                //AcDbText
                //AcDbOle2Frame
                //AcDbCircle

                if (cadObject.EntityName == "AcDbBlockReference")//为block类型的才判断
                {
                    if (cadObject.name == "A4横图框")
                    {
                        AcadBlockReference acadBlock = (AcadBlockReference)cadObject;
                        dynamic block = acadBlock.Explode();
                        if (((object[])(block)).Length > 0)
                        {
                            object double3_min, double3_max;
                            acadBlock.GetBoundingBox(out double3_min, out double3_max);
                            object LowerLeft = new double[2];//左下坐标，即xy最小值
                            object UpperRight = new double[2];//右上坐标，即xy最大值
                            ((double[])LowerLeft)[0] = ((double[])double3_min)[0];
                            ((double[])LowerLeft)[1] = ((double[])double3_min)[1];
                            ((double[])UpperRight)[0] = ((double[])double3_max)[0];
                            ((double[])UpperRight)[1] = ((double[])double3_max)[1];

                            //if (calcDiagonal(LowerLeft, UpperRight) > minDiagonal)
                            //{
                            //    ls_rec.Add(new object[] { LowerLeft, UpperRight });
                            //}
                        }
                    }

                }
            }
            doc.Close(false);
            AcdDoc.Close(false);
        }


        public void ExportBlocksToPDF()
        {
            // 启动AutoCAD
            Process acadProcess = new Process();
            acadProcess.StartInfo.FileName = @"E:\Program Files\Autodesk\AutoCAD 2014\acad.exe"; // 确保路径正确
            acadProcess.StartInfo.UseShellExecute = true;
            acadProcess.Start();

            // 等待AutoCAD启动完成
            System.Threading.Thread.Sleep(5000); // 等待时间根据实际情况调整

            // 向AutoCAD发送命令导出块到PDF
            Process cmdProcess = new Process();
            cmdProcess.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
            cmdProcess.StartInfo.RedirectStandardInput = true;
            cmdProcess.StartInfo.RedirectStandardOutput = true;
            cmdProcess.StartInfo.CreateNoWindow = true;
            cmdProcess.StartInfo.UseShellExecute = false;
            cmdProcess.Start();

            // 发送命令到AutoCAD命令行
            StreamWriter sw = cmdProcess.StandardInput;
            sw.AutoFlush = true;
            sw.WriteLine("(princ)\\n"); // 确保命令行准备好接收命令
            sw.WriteLine("_BLOCKEXPORT \"C:\\工程图\\11HZXC304-5.dwg\" \"C:\\temp\\\" \"CXHS\" PDF"); // 修改为你的DWG文件路径和输出路径
            sw.WriteLine("exit"); // 关闭命令行窗口
            sw.Close();
        }
public  void SaveSelectedObjects()
    {
        // 获取当前文档和数据库
        Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;
        Editor ed = doc.Editor;

        // 定义对角坐标点
        Point3d lowerLeft = new Point3d(0, 0, 0); // 左下角坐标
        Point3d upperRight = new Point3d(1000, 1000, 0); // 右上角坐标

        // 创建选择集
        PromptSelectionResult psr = ed.SelectWindow(lowerLeft, upperRight);

        if (psr.Status != PromptStatus.OK)
        {
            ed.WriteMessage("\n选择失败");
            return;
        }

        // 获取选择的对象
        SelectionSet ss = psr.Value;

        // 创建新数据库
        Database newDb = new Database(false, true);

        // 复制对象到新数据库
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            // 获取模型空间
            BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

            ObjectIdCollection ids = new ObjectIdCollection();
            foreach (SelectedObject so in ss)
            {
                if (so != null) // 确保选择的对象不为空
                {
                    ids.Add(so.ObjectId);
                }
            }

            // 在新数据库中获取模型空间
            using (Transaction newTr = newDb.TransactionManager.StartTransaction())
            {
                BlockTable newBt = (BlockTable)newTr.GetObject(newDb.BlockTableId, OpenMode.ForRead);
                BlockTableRecord newModelSpace = (BlockTableRecord)newTr.GetObject(newBt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                // 将选定的对象复制到新数据库的模型空间
                newDb.WblockCloneObjects(ids, newModelSpace.ObjectId, null, DuplicateRecordCloning.Ignore, false);
                newTr.Commit();
            }

            tr.Commit();
        }

        // 保存新数据库到文件
        string newDwgPath = @"C:\temp\newDrawing.dwg"; // 修改为你的新 DWG 文件路径
        newDb.SaveAs(newDwgPath, DwgVersion.Current);
        ed.WriteMessage("\n对象已成功导出到 {newDwgPath}");
    }


private static AcadApplication _app = null;

private static void Initialization()
{
    string programID = "AutoCAD.Application.19.1"; // 根据AutoCAD版本不同，程序ID也不同
    try
    {
        // 如果CAD已经打开，就直接获取
        _app = (AcadApplication)Marshal.GetActiveObject(programID);
    }
    catch
    {
        try
        {
            // 创建新的实例
            _app = (AcadApplication)new AcadDocument().Application;
        }
        catch
        {
            throw;
        }
    }
}
public static void Dwg2Pdf(string dwgFilePath)
{
    Initialization();

    AcadDocument doc = null;
    string destPath = string.Empty;
    try
    {
        //foreach (var f in files)
        //{
        doc = _app.Documents.Open(dwgFilePath, true);
            doc.SetVariable("sdi", 0);
            doc.SetVariable("Filedia", 0);
            doc.SetVariable("RASTERPREVIEW", 1);
            doc.SetVariable("BACKGROUNDPLOT", 0);
            string pc3Path = @"C:\Users\Lenovo\AppData\Roaming\Autodesk\AutoCAD 2014\R19.1\chs\Plotters\DWG To PDF.pc3";
            doc.ActiveLayout.ConfigName = pc3Path; // 不同版本的CAD可能不同
            doc.ActiveLayout.UseStandardScale = true;
            doc.ActiveLayout.StandardScale = AcPlotScale.acScaleToFit;
            doc.ActiveLayout.PlotType = AcPlotType.acExtents;
            doc.ActiveLayout.CenterPlot = true;
            doc.ActiveLayout.PlotRotation = AcPlotRotation.ac0degrees;
            doc.Plot.QuietErrorMode = true;
            destPath = Path.Combine(Path.GetDirectoryName(dwgFilePath), Path.GetFileNameWithoutExtension(dwgFilePath) + ".pdf");
            doc.Plot.PlotToFile(destPath);
            if (doc != null) doc.Close(false);
        //}
    }
    catch (System.Exception e)
    {
        throw e;
    }
    finally
    {
        try
        {
            doc.Close(false);
            _app.Quit();
        }
        catch { }
    }
}


public void GetBlockWholeScale()
{
    // 获取当前文档和数据库
    Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    // 提示用户选择一个块参照
    PromptEntityOptions peo = new PromptEntityOptions("\n请选择一个块参照: ");
    peo.SetRejectMessage("\n所选对象不是块参照，请重新选择。");
    peo.AddAllowedClass(typeof(BlockReference), true);

    PromptEntityResult per = ed.GetEntity(peo);
    if (per.Status != PromptStatus.OK)
    {
        return;
    }

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        try
        {
            // 打开所选实体
            BlockReference blockRef = tr.GetObject(per.ObjectId, OpenMode.ForRead) as BlockReference;
            if (blockRef != null)
            {
                // 获取块名
                BlockTableRecord btr = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                if (btr != null && !btr.IsAnonymous)
                {
                    // 遍历块定义中的所有对象并添加到 newIds
                    int i = 0;
                    foreach (ObjectId objId in btr)
                    {
                        i++;
                        string aa = "11";
                    }
                    // 获取 X、Y、Z 比例
                    double xScale = blockRef.ScaleFactors.X;
                    double yScale = blockRef.ScaleFactors.Y;
                    double zScale = blockRef.ScaleFactors.Z;

                    // 输出比例信息
                    ed.WriteMessage("\n块参照的 X 比例: {0}", xScale);
                    ed.WriteMessage("\n块参照的 Y 比例: {0}", yScale);
                    ed.WriteMessage("\n块参照的 Z 比例: {0}", zScale);
                }
                else
                {
                    ed.WriteMessage("\n所选块参照为匿名块，请选择非匿名块参照。");
                }
            }
            tr.Commit();
        }
        catch (System.Exception ex)
        {
            ed.WriteMessage("\n操作出错: {0}", ex.Message);
        }
    }
}

public void GetPaperSpaceViewportInfo()
{
    // 获取当前文档和数据库
    Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        try
        {
            // 打开块表
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

            // 打开图纸空间块表记录
            BlockTableRecord paperSpaceBtr = tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;

            int viewportCount = 0;
            // 遍历图纸空间中的所有实体
            foreach (ObjectId objId in paperSpaceBtr)
            {
                DBObject obj = tr.GetObject(objId, OpenMode.ForRead);
                if (obj is Viewport)
                {
                    Viewport vp = obj as Viewport;
                    if (vp.Number > 1) // 排除默认视口
                    {
                        viewportCount++;
                        // 获取视口的坐标和大小
                        Point3d center = vp.CenterPoint;
                        double width = vp.Width;
                        double height = vp.Height;

                        // 计算视口的左下角和右上角坐标
                        Point3d lowerLeft = new Point3d(center.X - width / 2, center.Y - height / 2, 0);
                        Point3d upperRight = new Point3d(center.X + width / 2, center.Y + height / 2, 0);

                        // 输出信息
                        ed.WriteMessage("\n图纸空间视口 {0} 信息：", viewportCount);
                        ed.WriteMessage("\n左下角坐标: ({0}, {1}, {2})", lowerLeft.X, lowerLeft.Y, lowerLeft.Z);
                        ed.WriteMessage("\n右上角坐标: ({0}, {1}, {2})", upperRight.X, upperRight.Y, upperRight.Z);
                        ed.WriteMessage("\n宽度: {0}", width);
                        ed.WriteMessage("\n高度: {0}", height);
                    }
                }
            }

            if (viewportCount == 0)
            {
                ed.WriteMessage("\n图纸空间中没有自定义视口。");
            }

            tr.Commit();
        }
        catch (System.Exception ex)
        {
            ed.WriteMessage("\n操作出错: {0}", ex.Message);
        }
    }
}


    } //类结束
} //命名空间
